package xyz.mumuwei.youthcourseserver.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import xyz.mumuwei.youthcourseserver.common.dto.PageDto;
import xyz.mumuwei.youthcourseserver.common.lang.Result;
import xyz.mumuwei.youthcourseserver.pojo.FileResources;
import xyz.mumuwei.youthcourseserver.pojo.User;
import xyz.mumuwei.youthcourseserver.service.FileService;
import xyz.mumuwei.youthcourseserver.service.UserService;
import xyz.mumuwei.youthcourseserver.utils.FileUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author mumuwei
 * @since 2022-02-19
 */
@Slf4j
@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${filePath}")
    private String filePath;
    @Value("${avatarPath}")
    private String avatarPath;

    private FileService fileService;
    private UserService userService;

    @Autowired
    public void setFileService(FileService fileService) {
        this.fileService = fileService;
    }

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    /**
     * 获取文件列表-分页
     */
    @GetMapping("/page")
    public Result page(PageDto pageDto){
        Page<FileResources> filePage = new Page<>(pageDto.getCurrent(), pageDto.getSize());
        IPage<FileResources> page = fileService.page(filePage,
                new QueryWrapper<FileResources>()
                        .like("name", pageDto.getKey())
                        .orderByDesc("create_time"));
        if(page == null){
            return Result.fail("获取失败！");
        }
        return Result.success(page);
    }

    /**
     * 获取文件列表-不分页
     */
    @GetMapping("/list")
    public Result list(){
        List<FileResources> list = fileService.list(new QueryWrapper<FileResources>()
                .orderByDesc("create_time"));
        if(list == null){
            return Result.fail("获取失败！");
        }
        return Result.success(list);
    }

    @PostMapping("")
    public Result update(FileResources fileResources){
        boolean update = fileService.updateById(fileResources);
        if(update){
            return Result.success("更新成功!");
        }
        return Result.fail("更新失败！");
    }

    /**
     * 修改文件状态
     * 0： 正常， 1： 锁定
     */
    @PostMapping("/state")
    public Result state(FileResources fileResources){
        FileResources file = new FileResources();
        file.setId(fileResources.getId());
        file.setState(fileResources.getState());
        boolean update = fileService.updateById(file);
        if (update){
            return Result.success("更新成功！");
        }
        return Result.fail("更新失败！");
    }

    /**
     * 根据id删除文件
     */
    @GetMapping("/d_{id}")
    public Result delete(@PathVariable Integer id){
        boolean b = fileService.removeById(id);
        if (b){
            return Result.success("删除文件成功！");
        }
        return Result.fail("删除文件失败！");
    }

    /**
     * 单文件上传
     */
    @PostMapping("/upload")
    public Result upload(MultipartFile file) throws IOException, NoSuchAlgorithmException {
        if(file.isEmpty()){
            return Result.fail("空文件，上传失败！");
        }
        return fileService.uploadFile(file);
    }

    @PostMapping("/upload/avatar")
    public Result uploadAvatar(@RequestAttribute Integer uid, MultipartFile file) throws IOException, NoSuchAlgorithmException {
        if(file.isEmpty()){
            return Result.fail("空文件，上传失败！");
        }
        return fileService.uploadAvatar(file, uid);
    }


    /**
     * 待开发！！！
     * 多文件上传
     */
    @PostMapping("/uploads")
    public Result uploads(HttpServletRequest request) throws IOException {
        List<MultipartFile> files = (List<MultipartFile>) ((MultipartHttpServletRequest) request).getFile("file");
        assert files != null;
        boolean flag = true;
        for (MultipartFile file: files){
            if(uploadFile(file)){
                flag = false;
                break;
            }
        }
        if(flag){
            return Result.success("文件上传成功！");
        }
        return Result.fail("文件上传失败！");
    }

    /**
     * 根据id下载文件
     */
    @GetMapping("/download_{id}")
    public void download(HttpServletResponse response, @PathVariable Integer id) throws IOException {
        FileResources resources = fileService.getById(id);
        File file = new File(filePath + "/" + resources.getUrl() + "/" + resources.getCode());
        // 判断文件是否存在
        if(file.exists()){
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(resources.getName(),"utf8"));
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            byte[] buffer = new byte[1024];
            //输出流
            FileInputStream fis= new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            OutputStream os = response.getOutputStream();
            int i = bis.read(buffer);
            while(i != -1){
                os.write(buffer);
                i = bis.read(buffer);
            }
        }
    }

    /**
     * 上传单文件
     */
    private boolean uploadFile(MultipartFile file) throws IOException {
        FileResources resources = new FileResources();
        // 获取文件名
        String fileName = file.getOriginalFilename();
        resources.setName(fileName);
        // 使用uuid生成新文件名
        assert fileName != null;
        String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + fileName.substring(fileName.lastIndexOf("."));
        resources.setCode(newFileName);
        // 获取年月日的日期格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());
        // 文件路径
        String fileUrl = filePath + "/" + format;
        resources.setUrl(fileUrl);
        // 判断文件夹是否存在
        File targetFile = new File(fileUrl);
        if(!targetFile.exists()){
            // 创建文件夹
            targetFile.mkdirs();
        }
        FileOutputStream fileOutputStream = new FileOutputStream(fileUrl + "/" + newFileName);
        fileOutputStream.write(file.getBytes());
        return fileService.save(resources);
    }

}

